home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 9
/
Night Owl CD-ROM (NOPV9) (Night Owl Publisher) (1993).ISO
/
050a
/
_tsgrep.zip
/
TSGREP.S
< prev
Wrap
Text File
|
1993-05-04
|
61KB
|
1,626 lines
/**************************************************************************
TSGREP ... A regular expression line extractor, v4.5
**************************************************************************/
/**************************************************************************
Forward Proc Declarations
**************************************************************************/
forward INTEGER proc multiple_filespecs // loads files separated by ^
(VAR STRING filespec)
forward proc loadfileList() // loads list of files
// from @file
forward proc nextfile_if_NOT_excluded() // loads file if NOT on
// excluded extension list
forward proc load_recursively // loads files from all sub-
(STRING arg) // directories below current
forward proc check_for_abort() // aborts between file loads
// if <escape>
forward proc end_processing // cleanup AND view
(INTEGER MODE)
forward proc interactive_setUp() // Setup for interactive
// operation
forward INTEGER proc ask_input() // Displays help; asks inputs
forward proc reload_files() // interactive mode : reload files
forward proc keystroke_help() // show legal keystrokes
forward proc process_AND() // processes -and- in search STRING
forward proc make_other_hit_lists() // for use by ...
forward proc toggle_hits() // toggles display of hit lines
forward proc goto_hit_List(INTEGER MODE) // goes to outfile
forward proc remove_file_from_hit_List() // removes a file & hits
forward proc undo_all_removes () // undoes removes
forward proc gotohit() // goes to another file
// from outfile
/*
forward STRING proc repl_char // replaces chars in a STRING
(STRING find_string,
STRING repl_string,
VAR STRING target)
*/
string proc repl_char(STRING find_string, STRING repl_string, VAR STRING target)
while Pos(find_string, target)
target = SubStr(target,
1,
Pos(find_string, target)-1
) +
repl_string +
SubStr(target,
Pos(find_string, target)+
Length(find_string),
Length(target)
)
endwhile
return(target)
end
forward proc hilite() // highlights text
forward proc unload() // unloads TSGREP.
/**************************************************************************
Variable & CONSTANT Declarations
**************************************************************************/
CONSTANT
interactive = 1,
cmdline = 0,
maxfn = 60, // :U: largest file name TSGREP can handle
maxspec = 120 // :U: largest input file spec
INTEGER
normal_Attr, // Attribute for normal text
hilite_Attr, // Attribute for highlighting
// (change these at the beginnig of
// Main(), NOT here.)
query_saves = TRUE, // :U: whether to query saves (interactive)
sgrepmode = cmdline, // initial mode
done_executed_once = FALSE, // for determining non-interactive
cid = 0, // first file loaded
oid = 0, // buffer to become output file
copy_of_list, // id for copy of above
files_only, // id for copy with only files
cfid = 0, // id for buffer with current files
id = 0, // id of file being processed
tid = 0, // a temp buffer used for
// searchstring processing
load_file = TRUE, // load outfile into editor
linenumbers = TRUE, // to include (OR NOT)
hits = 0, // hits counter
write_hits_flag = TRUE, // write hits in outfile
no_hitters_flag = FALSE, // were there any?
curr_file_hits = 0, // hits counter
name_line, // line filename placed on
files = 0, // file counter
lndigits = 5, // :U: max digits in a line number
linenumber = 0, // line number of find
auto, // original AutoIndent state
msgs, // original msg level state
wild, // original loadwild state
im , // original insert state
km , // original killbuffmax state
col = 1, // for gotohit
first_file_line = 12, // for gotohit
isloaded = 0, // for restoring curr files
sstring_hist_buff = 0, // history buffers for Ask()s
infile_hist_buff = 0,
options_hist_buff = 0,
outfile_hist_buff = 0,
getting_dirs_line = 9, // display lines
loading_files_line = 9,
getting_files_line = 9,
processing_line = 9,
files_loaded_line = 10,
files_processed_line = 10,
dirs_found_line = 10,
hits_line = 11,
press_any_key_line = 11
STRING
v[3]= '4.6', // :U: TSGREP version
ramdrive[3] = '', // :U: format: 'd:\' OR '\'
dir_spec[2] = '*.', // :U: change to '' if you use directories
// with an extension as part of name
pad[60] = ' ───────────────────────────────────────────────────────────',
name[maxfn] = '', // name of file being processed
name_prefix[4] = ' ', // :U: inserted into outfile before name
name_prefix_re[SizeOf(name_prefix)*2],
// version of above with, double length
name_suffix[1] = ':', // :U: inserted into outfile after name
options[25] ='', // search option, sgrep options
infile[maxspec] ='', // filespec for input
outfile[maxfn] ='', // filespec for output
sstring[255] ='', // search STRING
default_name[maxfn] ="TSGREP.TMP", // :U:default for above
default_name_2[maxfn] ="TSGREP.$MP",// :U:filespec for files-only list
OR_operator[4] = '-or-', // :U: represents | in searchstring
AND_operator[5] = '-and-', // :U: represents AND in searchstring
eq_char[2] = '\-', // :U: represents = in searchstring
space_char[1] = '_', // :U: represents in searchstring
less_than[2] = '[[', // :U: represents < in searchstring
greater_than[2] = ']]', // :U: represents > in searchstring
one_hit_flag[2] = '\1', // :U: flag for stop after 1 hit
dont_write_hits[2] = '\w', // :U: flag for NOT writing hits in outfile
no_line_numbers[2] = '\#', // :U: flag for NOT writing hits in outfile
dont_decode_spacechar[2] = '\_', // :U: flag for NOT decoding space_char
dont_load_outfile[2] = '\l', // :U: flag for NOT loading output file
no_re_flag[2] = '\x', // :U: flag for disable auto regexp mode
file_sep_char[1] = '^', // :U: file separator character
recurse_flag[1] = '+' , // :U: recursive search indicator
list_file_flag[1] = '@' , // :U: list file flag
line[255] = '' // used variously
/**************************************************************************
KEY DEFINITIONS
**************************************************************************/
keydef file
<alt enter> Disable(file) goto_hit_List(1)
BegLine() UpdateDisplay() Find(sstring, options)
<ctrl enter> Disable(file) goto_hit_List(1)
BegLine() UpdateDisplay() Find(sstring, options)
<alt escape> if sgrepmode == cmdline Exit() endif
<alt n> Find(sstring, options + '+')
<alt p> Find(sstring, options + 'b')
<alt h> keystroke_help()
<alt -> unload()
end
keydef hit_file
<alt enter> Disable(hit_file) gotohit()
BegLine() UpdateDisplay() Find(sstring, options)
<ctrl enter> Disable(hit_file) gotohit()
BegLine() UpdateDisplay() Find(sstring, options)
<alt escape> if sgrepmode == cmdline
GotoBufferId(oid) SaveFile() Exit() endif
<alt r> remove_file_from_hit_List()
<alt u> undo_all_removes()
<alt f> toggle_hits()
<alt n> if Find(name_prefix, '^+') hilite() endif
<alt p> if Find(name_prefix, '^b') hilite() endif
<alt h> keystroke_help()
<alt -> unload()
end
/**************************************************************************
PROCEDURES
**************************************************************************/
/*
proc viewfile()
string fn[32]='',
saved_wordset[32]= Set(wordset,chrset('a-zA-Z0-9!.\\:-'))
set(break,on)
pushposition()
pushblock()
if MarkWord()
fn = GetText(Query(BlockBegCol),
Query(BlockEndCol) - Query(BlockBegCol) + 1)
if fileexists(fn)
addhistorystr(fn, _edit_history_)
popposition()
editfile(fn)
if NOT List(currfilename(), 80)
abandonfile()
goto endit
endif
elseif fileexists('i:\usr\' + fn)
addhistorystr('i:\usr\' + fn, _edit_history_)
popposition()
editfile('i:\usr\' + fn)
if NOT List(currfilename(), 80)
abandonfile()
goto endit
endif
else
addhistorystr(fn, _edit_history_)
message("can't find ", fn)
popposition()
editfile(fn)
if numlines() and NOT List(currfilename(), 80)
abandonfile()
goto endit
else
// autoexec
abandonfile()
updatedisplay(_STATUSLINE_REFRESH_)
If not YesNo('Create '+ fn + '?') == 1
editfile(fn)
endif
endif
endif
else
popposition()
endif
endit:
set(break,OFF)
popblock()
Set(wordset,saved_wordset)
updatedisplay()
end
<alt e> viewfile()
proc whenloaded()
viewfile()
end
*/
proc MAIN()
normal_Attr = Query(TextAttr) // Attribute for normal text
hilite_Attr = Query(HiLiteAttr) // Attribute for highlighting
hits = 0 // balls = 2
files = 0 // runs = 0 <g>
load_file = TRUE // :U: load outfile into editor
linenumbers = TRUE // :U: to include (OR NOT)
write_hits_flag = TRUE // :U: write hits in outfile
if sstring_hist_buff == 0 // set up histories for Asks
sstring_hist_buff = GetFreeHistory()
infile_hist_buff = GetFreeHistory()
options_hist_buff = GetFreeHistory()
outfile_hist_buff = GetFreeHistory()
AddHistoryStr(default_name, outfile_hist_buff)
AddHistoryStr('i', options_hist_buff)
endif
if NOT done_executed_once // don't get after 1st time
options = GetEnvStr('OPTIONS')
AddHistoryStr(options, options_hist_buff)
infile = GetEnvStr('INFILE')
AddHistoryStr(infile, infile_hist_buff)
Lower(infile)
outfile = GetEnvStr('OUTFILE')
AddHistoryStr(outfile, outfile_hist_buff)
sstring = GetEnvStr('STRING')
AddHistoryStr(sstring, sstring_hist_buff)
endif
/*
if no Env STRINGs, go interactive
*/
if (sstring == '') OR done_executed_once // tests whether running
sgrepmode = interactive // from cmdline
interactive_setUp()
endif
/*
Set editor states
*/
Set(Break, ON)
im = Set(Insert,ON)
auto = Set(AutoIndent,OFF)
// msgs = Set(MsgLevel,_NONE_)
// msgs = Set(MsgLevel,_ALL_MESSAGES_)
msgs = Set(MsgLevel,_warnings_only_)
wild = Set(LoadWildFromInside, ON)
km = Set(KillMax, 0)
/*
The two lines below are unique for my setup only all my
when(event) macros check this variable. if TRUE, they do no
processing. This prevents any states from being set that I don't
want, e.g., AutoIndent.
*/
SetGlobalInt('Bypass_WhenSwitchToFile', TRUE)
SetGlobalInt('Bypass_WhenFirstEdited', TRUE)
/*
Set environment.
Parse option string AND set flags.
*/
if oid // to ensure minimal # of buffers
AbandonFile(oid)
endif
oid = CreateTempBuffer() // buffer to become output file
if Length(options) == 0 // set default options
options = 'i'
else
/*
Set 'don't write lines' flag
*/
if Pos(dont_write_hits, options)
options = repl_char(dont_write_hits, '', options) // get rid of option
write_hits_flag = FALSE
if NOT Pos(one_hit_flag, options) // set 'one hit' mode
options = options + one_hit_flag
endif
endif
/*
Set flag for loading the output file
*/
if Pos(dont_load_outfile, options)
load_file = FALSE // strip from options
options = repl_char(dont_load_outfile, '', options)
endif
/*
Set flag for line number suppression
*/
if Pos(no_line_numbers, options)
linenumbers = FALSE // strip from options
options = repl_char(no_line_numbers, '', options)
endif
endif
/*
Set reg exp mode if certain STRINGs in search STRING,
unless no_re_flag option used.
*/
line = sstring // to preserve state
Lower(sstring)
Lower(OR_operator) // in case someone defines
if (Pos (OR_operator, sstring) OR // variable with upper case
Pos(AND_operator, sstring) OR
Pos(".*", sstring) OR
Pos("[" , sstring)
) AND
NOT Pos(no_re_flag, options) AND // if NOT overridden
NOT Pos('x', options) // if NOT present
options = options + 'x'
endif // then
if Pos(no_re_flag, options) // strip out no_re_flag
options = repl_char(no_re_flag, '', options)
endif
sstring = line // to restore state
/*
Get rid of unusable options.
*/
if Pos('g', options)
options = repl_char('g', '', options)
endif
if Pos('b', options) // get rid of option we can't use
options = repl_char('b', '', options)
endif
if Pos('+', options) // get rid of option we can't use
options = repl_char('+', '', options)
endif
if Pos('l', options) // get rid of option we can't use
options = repl_char('l', '', options)
endif
/*
Decode Searchstring
Substitute < for less_than
Substitute > for greater_than
*/
sstring = repl_char(less_than, '<', sstring)
sstring = repl_char(greater_than, '>', sstring)
/*
Substitute | for OR_operator
*/
if Pos('x', options) // regexp only
sstring = repl_char(OR_operator, '|', sstring)
endif
/*
Substitute | for OR_operator
*/
if Pos('x', options) // regexp only
sstring = repl_char(OR_operator, '|', sstring)
endif
/*
Substitute = for eq_char
*/
sstring = repl_char(eq_char, '=', sstring) // decode equal signs
/*
Set up AND
*/
if Pos(AND_operator, sstring)
process_AND()
endif
/*
Substitute spaces for space char
*/
if NOT Pos(dont_decode_spacechar, options) // decode spaces
sstring = repl_char(space_char, ' ', sstring)
else
options = repl_char(dont_decode_spacechar, '', options)
endif
/*
Provide Default Braces if | is used with regular expr.
*/
if Pos('|', sstring) AND Pos('x', options)
tid = CreateTempBuffer()
InsertText(sstring) // put STRING in buffer
BegFile()
while lfind ('[\}]\|\c[~\{]', 'gx') // process {...}|...
InsertText('{') // becomes {...}|{...}
EndLine()
InsertText('}')
endwhile
while lfind ('[~\}]\c\|[\{]', 'gx')// process ...|{...}
InsertText('}') // becomes {...}|{...}
BegLine()
InsertText('{')
endwhile
if lfind ('[~\}]\|[~\{]', 'x') // process ...|...
Replace('{[~\}]}{\|}{[~\{]}', '\1}\2{\3', 'gnx')
BegLine() // becomes {...}|{...}
InsertText('{')
EndLine()
InsertText('}')
else
endif
BegLine()
sstring = GetText(1,CurrLineLen())
AbandonFile(tid)
GotoBufferId(oid)
endif
/*
Set default outfile
*/
if Length(outfile) == 0
outfile = default_name
endif
if SplitPath(outfile, _drive_ | _path_) == ''
outfile = ramdrive + outfile
endif
default_name_2 = SplitPath(outfile, _DRIVE_ | _NAME_) + '.$mp'
if fileexists(default_name_2)
erasediskfile(default_name_2)
editfile(default_name_2)
abandonfile()
endif
/*
Place header in outfile.
*/
GotoBufferId(oid)
AddLine('┌────────────────────────────────────────────────┐')
AddLine('│ TSGREP v' + v +
' ... David Marcus' +
Format(GetDateStr() + " " + GetTimeStr():18) +" │")
AddLine('└────────────────────────────────────────────────┘')
AddLine(" Searchstring: [" + sstring + "]")
if sgrepmode == cmdline
AddLine(" Input File Spec: " + GetEnvStr('INFILE'))
else
AddLine(" Input File Spec: LOADED FILES + " + infile )
endif
AddLine(" File created: " + outfile)
AddLine(" Options: [" + options + ']')
AddLine()
AddLine(" # Files: [")
AddLine(" # Hits: [")
AddLine()
AddLine( SubStr(pad,2,30) + ' Files With Hits ' +
SubStr(pad,2,30) )
AddLine()
/*
Screen display
*/
Message('')
Set(Cursor,Off)
HideMouse()
PopWinOpen( 08,12, 69,25, 1, '', normal_attr)
ClrScr()
Set(Attr, normal_attr)
VGotoXY(1,2)
WriteLine(Format(' ┌────────────────────────────────────────────────┐':-54))
WriteLine(Format(' │ TSGREP v'+v+' ... David Marcus' +
Format(GetDateStr() + ' ' + GetTimeStr() :18) +' │':-54))
WriteLine(Format(' └────────────────────────────────────────────────┘':-54))
WriteLine(Format(" Searchstring: [" + sstring + "]": -99))
if sgrepmode == cmdline
WriteLine(Format(" Input File Spec: " + GetEnvStr('INFILE'):-99))
else
WriteLine(Format(" Input File Spec: LOADED FILES + " + infile:-99 ))
endif
WriteLine(Format(" File created: " + outfile:-54))
WriteLine(Format(" Options: [" + options + ']':-54))
VGoToXY(1, files_processed_line)
WriteLine(Format(" Files Completed: [ ]":-54))
VGoToXY(1, hits_line)
WriteLine(Format(" # Hits: [ ]":-54))
Set(Attr,hilite_attr)
PutLine (" <escape> to abort", 50)
Set(Attr, normal_attr)
/*
Process multiple file input (OR single)
*/
multiple_filespecs(infile)
AbandonFile(GetBufferId('++unnamed++'))
cid = GetBufferId() // set 1st file ID
/*
Perform listfile loading.
*/
GotoBufferId(cid)
if Pos('' + list_file_flag + '',CurrFilename())
LoadFileList()
endif
nextfile_if_NOT_excluded()
cid = GetBufferId()
/* --------------------------------------------------------------------------
MAIN PROCESSING LOOP
*/
repeat
id = GetBufferId() // set id of file being processed
if Pos(outfile, CurrFilename())
nextfile_if_NOT_excluded()
id = GetBufferId()
endif
if Pos('' + list_file_flag + '',CurrFilename())
LoadFileList()
VGotoXY(1,getting_files_line)
PutLine(" Getting files from: [" + CurrFilename() + ']' ,42)
GotoBufferId(id)
if id == cid
AbandonFile()
nextfile_if_NOT_excluded()
id = GetBufferId()
cid = id
else
abandonfile()
nextfile_if_NOT_excluded()
id = GetBufferId()
endif
endif
name = CurrFilename() // get name of file
GotoBufferId(oid) // go to output buffer
GotoColumn(1)
if Length(name) // prevent blank at end
InsertText(name_prefix + name + name_suffix)
endif // insert file name
name_line = CurrLine() // later, go back to this line
VGotoXY(1,processing_line)
PutLine(" Processing: [" + name + ']' ,54)
CReturn() // AND creturn
GotoBufferId(id) // goto file being processed
BegFile()
while lFind(sstring, options)
AND CurrLine() <> NumLines() // stops processing if EOF
hits = hits + 1
curr_file_hits = TRUE
VGotoXY(25,hits_line)
PutLine(Str(hits)+']',10)
if write_hits_flag
linenumber = CurrLine() // remember line numer
UnMarkBlock() // mark found line as block
MarkLine()
MarkLine()
GotoBufferId(oid) // goto output buffer
CopyBlock() // copy block
BegLine() // insert line number
if linenumbers // if so flagged
InsertText(Format(linenumber:lndigits) + ' │ ')
endif
Down()
endif
GotoBufferId(id) // goto file being processed
if Pos(one_hit_flag, options)
EndFile()
else
Down() // AND down
BegLine() // to beginning of next line
endif
check_for_abort()
endwhile
BegFile() // reposition to top of file
files = files + 1
VGotoXY(25,files_processed_line)
PutLine(Str(files)+'] ~' + Str(NumFiles()-2) + ' to go',20)
NextFile_if_NOT_excluded()
id = GetBufferId()
if curr_file_hits == FALSE // if no hits, push file name
no_hitters_flag = TRUE
GotoBufferId(oid) //
DelLine() // get rid of blank line bottom
GotoLine(name_line)
InsertLine()
endif
curr_file_hits = FALSE
GotoBufferId(id)
if (GetBufferId() <> cid) // this processing unloads processed
PrevFile() // files so don't get VM slows
if (GetBufferId() <> cid)
AbandonFile()
endif
GotoBufferId(id)
endif
check_for_abort()
until GetBufferId() == cid
PrevFile()
AbandonFile()
VGotoXY(25,files_processed_line)
PutLine(Str(files)+']',22) // get rid of 'to go'
end_processing(0)
end
/**************************************************************************
end Processing (including list)
**************************************************************************/
proc end_processing(INTEGER mode) // mode 1 = interrupted
GotoBufferId(oid) // mode 0 = normal end
GotoLine(9) GotoPos(25)
if mode == 1
InsertText(Str(files)+']' + name_prefix + 'interrupted' + name_suffix)
else
InsertText(Str(files)+']')
endif
GotoLine(10) GotoPos(25)
InsertText(Str(hits)+']')
EndFile()
DelLine()
if no_hitters_flag
repeat
Up()
until CurrLineLen() == 0
CReturn()
InsertText( SubStr(pad,2,30) + 'Other Files Searched' +
SubStr(pad,2,30), _insert_)
endif
BegFile()
if NOT SaveAs(outfile, 1) // ,1 == overlay
Message('cannot save as ', outfile)
endif
if (sgrepmode == cmdline) AND (NOT load_file)
VGotoXY(3,press_any_key_line)
PutLine(Format("Press any key to continue": 57), 57)
Alarm()
GetKey()
AbandonEditor()
else
PopWinClose() // output area
/*
Get rid of all files other than the output file
*/
GotoBufferId(oid)
repeat
NextFile(_dont_load_)
if GetBufferId() <> oid
AbandonFile()
GotoBufferId(oid)
endif
until getbufferid() == oid
if sgrepmode == interactive
reload_files()
popwinclose() // fullscreen window
endif
/*
Reset editor
*/
Set(LoadWildFromInside, wild)
Set(AutoIndent,auto)
// Set(Break, OFF)
Set(Insert,im)
AbandonFile(cid)
AbandonFile(oid)
make_other_hit_lists() // ****
goto_hit_List(0)
SetGlobalInt('Bypass_WhenSwitchToFile', FALSE)
SetGlobalInt('Bypass_WhenFirstEdited', FALSE)
Set(KillMax,km)
Set(MsgLevel, Msgs)
Set(Cursor,On)
ShowMouse()
endif
done_executed_once = TRUE
UpdateDisplay()
hilite()
Message('Alt+H for help.')
end
proc goto_hit_List(INTEGER mode)
EditFile(outfile)
oid = GetBufferId()
Enable(hit_file)
if mode == 0
BegFile()
linenumber = 1
col = 1
if lFind(name_prefix,'')
first_file_line = CurrLine()
ScrollToRow( Query(ScreenRows) )
else
first_file_line = 12
endif
else
Down()
endif
end
/**************************************************************************
Load File List
**************************************************************************/
proc loadfileList() // note: this doesn't load nested files
// that is done in main processing
INTEGER
cid = GetBufferId()
EndFile() // to force processing in the order
BegLine() // files appear in the list file
repeat
if CurrLineLen() AND
Pos(recurse_flag, GetText(1, CurrLineLen()))
load_recursively( GetText(1, CurrLineLen() -1 ))
VGotoXY(1,loading_files_line)
PutLine(" Loading files from: [" + GetText(1, CurrLineLen()) + ']' ,54)
VGotoXY(1,files_loaded_line)
PutLine(" Files Inventoried: ["+Str(NumFiles())+"] " ,54)
elseif CurrLineLen() AND
(FileExists( GetText(1, CurrLineLen()) ))
VGotoXY(1,loading_files_line)
PutLine(" Loading files from: [" + GetText(1, CurrLineLen()) + ']' ,54)
VGotoXY(1,files_loaded_line)
PutLine(" Files Inventoried: ["+Str(NumFiles())+"] " ,54)
EditFile( '-a none.$$$ ' + GetText(1, CurrLineLen()) )
endif
GotoBufferId(cid)
check_for_abort()
until NOT Up()
if NumFiles() == 1
Warn('Cannot locate ANY files')
endif
GotoBufferId(cid)
AbandonFile()
NextFile()
VGotoXY(1,files_processed_line)
PutLine(" Files Completed: [ ]" ,54)
return()
end
/**************************************************************************
Go To Hit
**************************************************************************/
proc GotoHit()
STRING
fn[maxfn] = ''
top:
if GetBufferId() == files_only
toggle_hits()
else
EditFile(outfile)
endif
BegLine()
if NumLines() == 2
Warn('No files matched file spec ....')
AbandonEditor()
endif
if CurrLine() < first_file_line // get to first hit if at top of file
GotoLine(first_file_line)
endif
if (CurrLine() < first_file_line) // get to first hit if at top of file
OR (currLineLen() == 0)
GotoLine(first_file_line)
endif
if (GetText(1,1) == '─') OR (currLineLen() == 0)
repeat
Down()
until GetText(1,Length(name_prefix)) == name_prefix OR
(numlines() == CurrLine())
endif
if numlines() == CurrLine()
repeat
Up()
until GetText(1,Length(name_prefix)) == name_prefix OR
(CurrLine() <= first_file_line)
endif
col = CurrCol() // get currcol in case search was used
BegLine()
PushPosition() // remember line
if GetText(1,Length(name_prefix)) == name_prefix
linenumber = 0
else // get line number
linenumber = Val( GetText(1,lndigits))
while NOT (GetText(1,Length(name_prefix)) == name_prefix)
AND
(CurrLine() >= first_file_line)
Up()
endwhile // get file name if NOT on it
endif
fn = ( GetText( Length(name_prefix) + 1,
CurrLineLen() - Length(name_prefix)
- Length(name_suffix) ) )
PopPosition() // go back to line
if FileExists(fn)
EditFile( fn )
if linenumber
GotoLine(linenumber)
GotoColumn(col - 9) // if isrch was used
endif
if write_hits_flag == FALSE // hits were NOT written
lFind(sstring, options) // so goto first
endif
Message("'ALT-ENTER' to reselect")
Disable(hit_file)
Enable(file)
UpdateDisplay()
pad = SubStr(pad, 1, 44 - Length(CurrFilename()))
ScrollToRow(12)
else
if Length(fn)
Warn("Can't find file [" , fn, '] ' )
Enable(hit_file)
Return()
endif
goto top
endif
end
/**************************************************************************
Load Multiple Filespecs
**************************************************************************/
INTEGER proc multiple_filespecs(VAR STRING filespec)
INTEGER
files = 0,
passes = 1
STRING
file_to_load[maxspec]='',
prev_path[maxfn - 14]='',
prev_drive[2]='',
orig_file_sep_char[1] = file_sep_char
repeat // repeat loop 2x, once for
// unmodified file_sep_char
// once for it set to ' '
//
while Pos(file_sep_char, filespec)
file_to_load = SubStr(
filespec,
1,
Pos(file_sep_char, filespec)-1 )
/*
Assign previous filespecs path if none
*/
if SplitPath(file_to_load, _drive_ | _path_) == ''
file_to_load = prev_drive + prev_path + file_to_load
endif
/*
Assign previous filespecs drive if none
*/
if SplitPath(file_to_load , _drive_) == ''
file_to_load = prev_drive + file_to_load
endif
prev_drive = SplitPath(file_to_load , _drive_)
prev_path = SplitPath(file_to_load , _path_)
if Pos(recurse_flag, file_to_load)
load_recursively(SubStr(file_to_load,
1,
Length(file_to_load)-1))
else
if FileExists(file_to_load)
VGotoXY(1,loading_files_line)
PutLine(" Loading files from: [" + GetText(1, CurrLineLen()) + ']' ,54)
VGotoXY(1,files_loaded_line)
PutLine(" Files Inventoried: ["+Str(NumFiles())+"] " ,54)
EditFile('-a none.$$$ ' + file_to_load) // edit first spec
endif
endif
filespec = SubStr( // remove first spec
filespec, // from filespec
Pos(file_sep_char, filespec)+1,
Length(filespec)
)
files = files + 1
endwhile
passes = passes + 1
file_sep_char = ' '
until passes == 2
file_sep_char = orig_file_sep_char // reset
/*
Assign previous filespecs path if none
*/
if SplitPath(filespec, _drive_ | _path_) == ''
filespec = prev_drive + prev_path + filespec
endif
/*
Assign previous filespecs drive if none
*/
if SplitPath(filespec , _drive_) == ''
filespec = prev_drive + filespec
endif
if Pos(recurse_flag, filespec)
load_recursively(SubStr(filespec, 1, Length(filespec)-1))
else
EditFile('-a none.$$$ ' + filespec) // edit last spec
endif
return(files)
end
/**************************************************************************
Replace Character In STRING
**************************************************************************/
/**************************************************************************
NextFile if NOT Excluded
**************************************************************************/
proc nextfile_if_NOT_excluded()
STRING
exclude[255] = GetEnvStr('EXCLUDE')
+ ' .img .exe .com .dll .tif .pcx .$hp .$sc .cif .vgr', // :U:
fn[8] = '',
fe[4] = ''
/*
Goes to next file if NOT on excluded .ext list.
*/
check_for_abort()
top:
NextFile(_DONT_LOAD_) // goto bufferid w/o load
fn = SplitPath(CurrFilename(),_NAME_)
fe = SplitPath(CurrFilename(),_EXT_)
if Pos(Format( fe : -4) , exclude)
OR ((fn + fe) == 'none.$$$')
OR ((fn + fe) == OUTFILE)
OR ((fn + fe) == default_name_2)
AbandonFile()
goto top
endif
if Length(CurrFilename()) and FileExists((CurrFilename()))
EditFile(CurrFilename()) // to load file
endif
end
/**************************************************************************
Load Recursively
**************************************************************************/
proc load_recursively(STRING arg)
/*
Creates AND loads a list file that has
one line for each subdirectory under the
specified directory. Each line included the filespec
to be searched.
*/
STRING
dir[maxspec] = SplitPath(arg, _DRIVE_ | _PATH_ ),
filespec[maxspec]= SplitPath(arg, _NAME_ | _EXT_ ),
dir_name[maxspec - 12] = '',
dirfile[SizeOf(ramdrive) + 12] = ramdrive + '$temp$.$$$'
INTEGER
listfile = 0, // bufferid for listfile
dirlist = 0, // bufferid for dir list
dir_list_buff = 0,
dir_counter = 0
if FileExists(arg) // if there are files in arg
GotoBufferId(listfile) // add to list file
AddLine(arg)
endif
if listfile
AbandonFile(listfile)
endif
if dirlist
AbandonFile(dirlist)
endif
listfile = CreateTempBuffer() // bufferid for listfile
dirlist = CreateTempBuffer() // bufferid for dir list
dir_name = dir
VGotoXY(1,getting_dirs_line)
PutLine(" Finding Dirs Under: [" + dir + ']' ,54)
VGotoXY(1,dirs_found_line)
PutLine(" Dirs Found: [ ]" ,54)
EndFile() // to force processing in the order
top:
/*
Create buffer to hold a directory AND get
it in there.
*/
if dir_list_buff
AbandonFile(dir_list_buff)
endif
dir_list_buff = CreateTempBuffer()
DOS('dir ' + dir + dir_spec + ' > ' + dirfile, _dont_clear_ )
GotoXY(1,1) // avoids some DOS pita-ness
insertfile (dirfile)
VGotoXY(1,getting_dirs_line)
PutLine(" Finding Dirs Under: [" + dir + ']' ,54)
repeat // for each line in directory
check_for_abort()
BegLine()
while ( // delete lines we don't want
CurrChar() == Asc(' ') OR //
CurrChar() == Asc('.') OR
CurrLineLen() == 0
)
AND
(NumLines() <> CurrLine())
DelLine()
endwhile
line = GetText(1, CurrLineLen()) // work with line we do
if NOT Pos('<DIR>', line) // if NOT a directory
DelLine() // delete it
else
dir_counter = dir_counter + 1
VGotoXY(1,dirs_found_line)
PutLine(" Dirs Found: ["+Str(dir_counter)+"] "
+ dir_name ,54)
dir_name = dir + GetText(1,Pos(' ', line)-1)
if GetText(12,1) <> ' ' // check for .nnn dir name
dir_name = dir_name + '.' + GetText(10,3)
elseif GetText(11,1) <> ' ' // check for .nn dir name
dir_name = dir_name + '.' + GetText(10,2)
elseif GetText(10,1) <> ' ' // check for .n dir name
dir_name = dir_name + '.' + GetText(10,1)
endif
GotoBufferId(dirlist) // add to the list of dirs
AddLine(dir_name) // to process
if FileExists(dir_name + '\' + filespec)
GotoBufferId(listfile) // add to list file
AddLine(dir_name + '\' + filespec)
endif
GotoBufferId(dir_list_buff)
endif
until NOT Down()
AbandonFile() // abandon dir_list_buff
/*
repeat for any directories left
to process
*/
GotoBufferId(dirlist)
BegFile()
if NumLines() AND CurrLineLen()
dir = GetText(1,CurrLineLen()) + '\' // set next dir to process
DelLine() // delete it from list
goto top // loop around
endif
AbandonFile(dirlist)
GotoBufferId(listfile) // mark all of listfile
BegFile()
MarkLine()
EndFile()
MarkLine()
if FileExists('' + list_file_flag + '')
EraseDiskFile('' + list_file_flag + '')
endif
EditFile('' + list_file_flag + '') // copy to an @file file
CopyBlock() // which will be processed
// AND abandoned by TSGREP
AbandonFile(listfile)
EraseDiskFile(dirfile)
Message('')
end
/**************************************************************************
Process "AND" in Searchstring
**************************************************************************/
proc process_AND()
STRING
part1[maxspec] = '',
part2[maxspec] = ''
part1 = SubStr(sstring, 1, Pos(AND_operator,sstring) - 1)
part2 = SubStr(sstring, Pos(AND_operator,sstring) + Length(AND_operator), Length(sstring))
sstring = '{'+ part1 + '.*' + part2 + '}|{' +
part2 + '.*' + part1 + '}'
end
/**************************************************************************
Check for Abort
**************************************************************************/
proc check_for_abort()
if KeyPressed() AND GetKey() == <escape>
PushKey(<enter>) // bypasses 'press any key'
end_processing(1)
halt // Avoid going back to where
endif // check_for_abort was called
end
/**************************************************************************
Create Files-Only List AND Create Backup Complete List
**************************************************************************/
proc make_other_hit_lists()
msgs = Set(MsgLevel,_warnings_only_)
if copy_of_list
AbandonFile(copy_of_list)
endif
copy_of_list = CreateTempBuffer()
InsertFile(outfile)
if files_only
AbandonFile(files_only)
endif
files_only = CreateTempBuffer()
message(default_name_2)
SaveAs(default_name_2,1)
EditFile(default_name_2)
AbandonFile(files_only)
files_only = GetBufferId()
InsertFile(outfile)
Set(KillMax,0)
repeat
if ( Val(GetText(1, lndigits)))
DelLine()
else
Down()
endif
until NumLines() == CurrLine()
Set(KillMax,km)
ForceChanged(FALSE)
GotoBufferId(oid)
PopBlock()
Set(MsgLevel,msgs)
end
/**************************************************************************
Setup Stuff for Interactive Operation
**************************************************************************/
proc interactive_setUp()
cid = GetBufferID()
repeat
if ischanged() and query_saves
updatedisplay()
case YesNo( 'Save changes?')
when 0, 2, 3 // Escape OR Cancel
if GetBufferID() == cid // reset cid
prevfile()
cid = GetBufferID()
nextfile()
endif
name = CurrFileName()
linenumber = CurrLine()
Message('Reloading ' + name)
AbandonFile()
editfile(name)
GoToLine(linenumber)
UpDateDisplay(_STATUSLINE_REFRESH_)
when 1 // Yes
SaveFile() //
endcase
else
SaveFile()
endif
NextFile()
until cid == GetBufferID()
PopWinOpen( 01,01, Query(ScreenCols), Query(ScreenRows), 0, '',
Query(OtherWinBorderAttr)) // to blank screen
ClrScr()
if NOT ask_input()
AbandonFile(cfid)
PopWinClose() // full screen window
AbandonFile(GetBufferId('++unnamed++'))
halt
endif
msgs = Set(MsgLevel,_NONE_)
if GetBufferId(outfile)
AbandonFile(GetBufferId(outfile))
endif
Set(MsgLevel,msgs)
if infile == '' // seems to required
infile = 'none.$$$' // else a file is dropped!
endif
/*
List currently-loaded files for later reload
*/
PrevFile(_DONT_LOAD_) // currently-loaded files
NextFile(_DONT_LOAD_) // start from a file
cid = GetBufferId()
if cfid
AbandonFile(cfid)
endif
cfid = CreateTempBuffer() // buffer to hold list
GotoBufferId(cid)
repeat
id = GetBufferId()
name = CurrFilename() // file name
isloaded = iif(NumLines(), 1, 0) // whether to reload
linenumber = CurrLine() // line to which to go
GotoBufferId(cfid)
AddLine(Format(name : -maxfn) +
Format(isloaded) +
Str(linenumber) )
GotoBufferId(id)
NextFile(_DONT_LOAD_)
until GetBufferID() == cid
end
/**************************************************************************
Reload Files (Interactive Mode)
**************************************************************************/
proc reload_files()
INTEGER count = 0
cid = GetBufferId()
if NOT cfid // in case current file list NOT built
return()
endif
GotoBufferId(cfid)
BegFile()
repeat
count = count + 1
GotoBufferId(cfid)
if GetText(1,11) == '++unnamed++'
// do nothing
elseif GetText(maxfn + 1, 1) == '1'
EditFile(SubStr(
GetText(1,maxfn), 1, Pos(' ', GetText(1,maxfn))
) +
'-n' + GetText(maxfn + 2, lndigits)
)
else
EditFile(outfile + ' ' + GetText(1,maxfn))
endif
GotoBufferId(cfid)
until NOT Down()
AbandonFile(cfid)
end
/**************************************************************************
Toggle From Showing Detail to NOT Showing It
**************************************************************************/
proc toggle_hits()
INTEGER
row = CurrRow()
if GetBufferId() == oid
PushPosition()
EndLine()
lFind(name_prefix, '^b')
row = CurrRow()
line=GetText(1,CurrLineLen())
PopPosition()
GotoBufferId(files_only)
BegFile()
lFind(line,'^')
ScrollToRow(row)
elseif getbufferid() == files_only
EndLine()
lFind(name_prefix, '^b')
line=GetText(1,CurrLineLen())
ForceChanged(FALSE)
GotoBufferId(oid)
BegFile()
lFind(line,'^')
ScrollToRow(row)
endif
UpdateDisplay()
hilite()
end
/**************************************************************************
Remove File From Hit List
**************************************************************************/
proc remove_file_from_hit_List()
INTEGER
startbuffer = GetBufferId(),
counter = 0
Set(KillMax, 0)
PushBlock()
PushPosition()
UnMarkBlock()
EndLine()
if startbuffer == files_only
if GetText(1,Length(name_prefix)) <> name_prefix
Warn('NOT on file name')
return()
endif
line = GetText(1,80)
DelLine()
ForceChanged(FALSE)
GotoBufferId(oid)
begfile()
if NOT lFind(line, '^')
Warn("can't find ", line)
Set(KillMax, km)
return()
endif
endif
name_prefix_re = '' // build an escaped reg_exp version
repeat // of name_prefix (because RE is used)
counter = counter + 1 // in alt-p and alt-n)
if Pos(name_prefix[counter], '.^$\|?[]*+@#{}')
name_prefix_re = name_prefix_re + '\'
endif
name_prefix_re = name_prefix_re + name_prefix[counter]
until counter == Length(name_prefix)
if (GetText(1,Length(name_prefix)) == name_prefix) AND Down() AND
(GetText(1,Length(name_prefix)) == name_prefix) OR
(NumLines() <= (CurrLine() + 1))
Up()
line = GetText(1,80)
DelLine()
PopBlock()
elseif lFind('{'+ name_prefix_re + '}|{─}', '^x') AND
Up() AND
MarkLine() AND
lFind(name_prefix, '^b') AND
MarkLine()
GotoBlockBegin()
line = GetText(1,80)
GotoBlockEnd()
Down()
DelBlock()
endif
PopBlock()
if startbuffer == oid
GotoBufferId(files_only)
if lFind(line, '^')
DelLine()
ForceChanged(FALSE)
endif
endif
PopPosition()
BegLine()
Set(KillMax, km)
ForceChanged(FALSE)
UpdateDisplay()
hilite()
end
/**************************************************************************
Undo All "Remove File From Hit List"
**************************************************************************/
proc undo_all_removes()
INTEGER
row = 0
PushBlock()
UnMarkBlock()
GotoBufferId(oid)
line = GetText(1,80)
row = CurrRow()
BegFile() MarkLine()
EndFile() MarkLine()
Set(KillMax,0)
DelBlock()
Set(KillMax,km)
GotoBufferId(copy_of_list)
BegFile() MarkLine()
EndFile() MarkLine()
GotoBufferId(oid)
CopyBlock()
PopBlock()
lFind(line, '^')
PushPosition()
AbandonFile(files_only)
AbandonFile(copy_of_list)
make_other_hit_lists()
PopPosition()
ScrollToRow(row)
UpdateDisplay()
hilite()
end
proc hilite()
UpdateDisplay() // seems needed twice sometimes
UpdateDisplay()
if PosLastNonWhite() - CurrPos() + 1
PutAttr(Query(HiLiteAttr), PosLastNonWhite() - CurrPos() + 1)
endif
end
/**************************************************************************
Ask for Input
**************************************************************************/
INTEGER proc ask_input()
PopWinOpen( 01,05, Query(ScreenCols), Query(ScreenRows), 2, '',
Query(OtherWinBorderAttr)) // help screen
Set(y1,1)
WriteLine('Your search STRING may be any TSE search string. However:')
WriteLine(' * You may use ' + or_operator + ' instead of |.')
WriteLine(' * You may use ' + space_char + ' instead of space.')
WriteLine(' * You may use ' + eq_char + ' for =.')
WriteLine(' * You may use ' + less_than + ' for <.')
WriteLine(' * You may use ' + greater_than + ' for >.')
WriteLine('(These required for command line operation.)')
WriteLine('')
WriteLine('If ' + or_operator + ' is not surrounded by }{, TSGREP will supply the braces. So,')
WriteLine('"menu' + or_operator + 'proc' + or_operator + 'keydef" gets turned into "{menu}|{proc}|{keydef}".')
WriteLine('All braces you do supply are honored.')
WriteLine('')
WriteLine('Use '+ and_operator + ' to mean "and" in the search string. May be only used')
WriteLine('once in the string. Order is not important; a'+ and_operator + 'b means')
WriteLine('(a.*b) OR (b.*a) ... and that is exactly how it is implemented.')
WriteLine('')
WriteLine('If combining OR with AND, use braces to surround the terms')
WriteLine('being ORd. For instance: "sort'+ and_operator + 'b{search' + or_operator + 'subtotal}".')
if NOT
Ask(Format("Search string?" : - Query(ScreenCols)),
sstring, sstring_hist_buff)
PopWinCLose() // help screen
return(FALSE)
endif
ClrScr()
WriteLine('Files currently in the ring are always searched. Files specified at this')
WriteLine('prompt are searched additionally. The original ring is restored after the')
WriteLine('searches; no additional files are left loaded.')
WriteLine('')
WriteLine('Use ' + file_sep_char + ' as a separator for multiple files, as in "*.q' + file_sep_char + '*.inc' + file_sep_char + 'q:c*.??c".')
WriteLine('If you use ' + file_sep_char + ' and a filespec has no drive and path, the ones for the')
WriteLine('preceding filespec are applied to it. For instance:')
WriteLine(' i:\usr\*.txt' + file_sep_char + '*.doc' + file_sep_char + 'c:\*.txt' + file_sep_char + '*.doc')
WriteLine('is processed as')
WriteLine(' i:\usr\*.txt' + file_sep_char + 'i:\usr\*.doc' + file_sep_char + 'c:\*.txt' + file_sep_char + 'c:\*.doc')
WriteLine('')
WriteLine('Files with "' + list_file_flag + '" in any position of the name are treated as list files.')
WriteLine('List files may contain specific file names, wildcarded filespecs, and')
WriteLine('additional listfile names. Place one spec per line, starting each in ')
WriteLine('column 1. You can use multiple list files on the command line or ')
WriteLine('combine them with other filespecs.')
WriteLine('')
WriteLine('Add ' + recurse_flag + ' to the end of a filespec to have TSGREP process')
Write ('matching files in all subdirectories of the specified one.')
Set(y1,1)
if NOT
Ask(Format("File(s) OR filespec to search?" : - Query(ScreenCols)),
infile, infile_hist_buff)
PopWinCLose() // help screen
return(FALSE)
endif
ClrScr()
WriteLine('Options may be include any TSE search option except "b", "g" AND "+".')
WriteLine('TSE options you can use include i x w ^ AND $.')
WriteLine('')
WriteLine('Default options are "i". If any of these strings are contained in the')
WriteLine('search string, "x" is automatically added to the options unless "' + no_re_flag + '" is')
WriteLine('is used as an option: ' + or_operator + ' .* [ '+ and_operator + '.')
WriteLine('')
WriteLine('Use ' + no_line_numbers + ' in options to suppress line numbers.')
WriteLine(' ' + one_hit_flag + ' to stop searching each file after 1 hit found.')
WriteLine(' ' + dont_decode_spacechar + ' to force reading of "' + space_char + '" in the search STRING as underscores')
WriteLine(' rather than spaces.')
WriteLine(' ' + dont_write_hits + ' to NOT write lines with hits to outfile; only list file names.')
WriteLine(' ' + no_re_flag + ' to overide automatic kick in of regular expression.')
WriteLine(' ' + dont_load_outfile + ' to not have the output file loaded.')
Set(y1,1)
if NOT
Ask(Format('Search options?': - Query(ScreenCols)),
options, options_hist_buff)
PopWinCLose() // help screen
return(FALSE)
endif
ClrScr()
WriteLine('Outfile is optional; the default is ' + default_name+ '.')
Set(y1,1)
if NOT
Ask(Format('File to create?': - Query(ScreenCols)),
outfile, outfile_hist_buff)
PopWinClose() // help window
return(FALSE)
else
PopWinClose() // help window
return(TRUE)
endif
return(TRUE)
end
/**************************************************************************
Unload TSGREP
**************************************************************************/
proc unload()
cid = GetBufferID()
AbandonFile(copy_of_list)
AbandonFile(files_only)
if EditFile(default_name_2)
KillFile()
AbandonFile()
endif
gotobufferid(oid)
updatedisplay()
QuitFile()
GotoBufferID(cid)
PurgeMacro('sgrep')
Message("TSGREP purged.")
Alarm()
end
/**************************************************************************
Keystroke Help
**************************************************************************/
Help keystrokes
title = 'Keystrokes for TSGREP:'
width = 78
height = 17
x = 1 y = 2
''
'■ While you are in the file listing hits:'
''
' <alt F> Toggle showing lines with hits or only filenames'
' <alt N>, <alt P> Go to next/prev file in listing'
' <alt R>, <alt U> Remove the entries for a file/undo all removes'
' <alt enter> Edit file AND go to line the cursor is on'
' <alt h> Pop up this help window.'
' <alt -> Unload TSGREP. (All keys revert to normal use.)'
''
'■ While editing one of the files listed'
''
' <alt N>, <alt P> Goto next/prev hit in this file'
' <alt enter> Go back to the file listing hits'
' <alt h> Pop up this help window.'
' <alt -> Unload TSGREP. (All keys revert to normal use.)'
''
' Press any key when you have memorized this screen.'
end
proc keystroke_help()
Message('Press any key to continue')
showhelp(keystrokes)
updatedisplay()
end